#ifndef FILESYSTEM_H
#define FILESYSTEM_H

#include "../types.h"

/* The path separator depending of the system */
#ifdef UNIX
#define PTHSPRT '/'
#else
#define PTHSPRT '\\'
#endif

#define MAX_DIRNAME 255
#define MAX_ENTRIES 255

typedef enum
{
    ISOFS,
    DIRFS
} FSType;

typedef struct
{
    FSType type;
    char *prefix;
    void *system;
} System;

typedef enum
{
    FILEACCESS_NONE = 0,
    FILEACCESS_READ = 1,
    FILEACCESS_WRITE = 2,
    FILEACCESS_APPEND = 4,
    FILEACCESS_CREATE = 8
} FileAccess;

typedef enum
{
    FILEMOVE_BEGIN = 0,
    FILEMOVE_CURRENT = 1,
    FILEMOVE_END = 2
} FileMove;

typedef enum
{
    FILETYPE_NORMAL = 1,
    FILETYPE_DIRECTORY = 2
} FileType;

typedef struct
{
    char name[MAX_DIRNAME]; /* TODO: STATIC */
    u64 size;
    u16 access; /* unix 777 */
    FileType type;

    u8 isOnSectorSystem;
    u32 startSector;
    u32 numSectors;
} FileInfo;

typedef struct
{
    char *drive;
    char *path;
    char *file;
    char *ext;
} SplittedPath;

SplittedPath splitPath(const char *filename);
void freeSplittedPath(SplittedPath *path);
void fileinfo_init(FileInfo *fi);

void fs_free(System *fs);
char *fs_getRealPath(System *fs, const char *inpath);
FileInfo fs_getFileInfo(System *fs, const char *filename);
s32 fs_openFile(System *fs, const char *filename, FileAccess access);
s32 fs_ownsHandle(System *fs, u32 handle);
s32 fs_readFile(System *fs, u32 handle, char *pointer, u32 size);
s32 fs_readFileToAddr(System *fs, u32 handle, u32 addr, u32 size);
void fs_closeFile(System *fs, u32 handle);
u32 fs_getDirListing(System *fs, const char *path, FileInfo **listing);
void fs_freeDirListing(System *fs, FileInfo *listing);
s32 fs_seekFile(System *fs, u32 handle, s32 position, FileMove type);
s32 fs_writeFile(System *fs, u32 handle, u8 *pointer, u32 size);
s32 fs_writeFileFromAddr(System *fs, u32 handle, u32 addr, u32 size);
s8 fs_mkdir(System *fs, const char *dir, s32 mode);

#endif

